package com.ricky.db;

import java.lang.reflect.Field;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.ricky.config.ConfigData;
import com.ricky.db.model.Model;
import com.ricky.utils.ConfigHelper;
import com.ricky.utils.Utils;

/**
 * 数据处理
 * 
 * @author rik
 * 
 */
public class DBHelper {

	protected static Logger log = Logger.getLogger(DBHelper.class);

	private static Mongo m = null;
	public static DB db = null;

	/**
	 * 初始化
	 */
	public static void init() {
		try {
			m = new Mongo("localhost", 27017);
			log.info("实例化mongoDB");
			db = m.getDB(ConfigData.serverinfo.getMongoDB());
		} catch (UnknownHostException e) {
			log.error(e.getMessage(), e);
		} catch (MongoException e) {
			log.error(e.getMessage(), e);
		}
	}

	/**
	 * 查询一个对象
	 * 
	 * @param dbName
	 * @param dtName
	 * @param query
	 * @return
	 */
	public static DBObject queryOne(String dtName, DBObject query) {
		DBObject dbo = null;
		dbo = db.getCollection(dtName).findOne(query);
		return dbo;
	}
	
	/**
	 * 查询一个对象
	 * 
	 * @param dbName
	 * @param dtName
	 * @param query
	 * @return
	 */
	public static DBObject queryOne(String dtName, String queryJson) {
		DBObject dbo = null;
		Map<String,Object> m=Utils.jsonToMap(queryJson);
		DBObject query=new BasicDBObject();
		for(Entry<String, Object> e: m.entrySet())
			query.put(e.getKey(), e.getValue());
		dbo = db.getCollection(dtName).findOne(query);
		return dbo;
	}

	/**
	 * 查询多个对象
	 * 
	 * @param dbName
	 * @param dtName
	 * @param query
	 * @return
	 */
	public static List<DBObject> query(String dtName, DBObject query) {
		DBCursor cursor = null;
		cursor = db.getCollection(dtName).find(query);
		List<DBObject> li = new ArrayList<DBObject>();
		try {
			while (cursor.hasNext())
				li.add(cursor.next());
		} finally {
			cursor.close();
		}
		return li;
	}
	
	/**
	 * 查询多个对象
	 * 
	 * @param dbName
	 * @param dtName
	 * @param query
	 * @return
	 */
	public static List<DBObject> query(String dtName, String queryJson) {
		DBCursor cursor = null;
		Map<String,Object> m=Utils.jsonToMap(queryJson);
		DBObject query=new BasicDBObject();
		for(Entry<String, Object> e: m.entrySet())
			query.put(e.getKey(), e.getValue());
		cursor = db.getCollection(dtName).find(query);
		List<DBObject> li = new ArrayList<DBObject>();
		try {
			while (cursor.hasNext())
				li.add(cursor.next());
		} finally {
			cursor.close();
		}
		return li;
	}

	/**
	 * 查询多个对象
	 * 
	 * @param dbName
	 * @param dtName
	 * @param query
	 * @return
	 */
	public static <T extends Model> List<T> queryEntitys(String dtName, String queryJson,Class<T> cls) {
		DBCursor cursor = null;
		Map<String,Object> m=Utils.jsonToMap(queryJson);
		DBObject query=new BasicDBObject();
		for(Entry<String, Object> e: m.entrySet())
			query.put(e.getKey(), e.getValue());
		cursor = db.getCollection(dtName).find(query);
		List<T> li = new ArrayList<T>();
		T i=null;
		try {
			while (cursor.hasNext())
			{
				i=DBObjectToModel(cursor.next(),cls);
				li.add(i);
			}
		} finally {
			cursor.close();
		}
		return li;
	}
	/**
	 * 保存一个对象
	 * 
	 * @param dtName
	 * @param query
	 */
	public static DBObject update(String dtName, DBObject q,DBObject o) {
		DBCollection dbc = db.getCollection(dtName);
		dbc.update(q, o, true, false);
		return o;
	}

	/**
	 * 保存实体
	 * 
	 * @param dtName
	 * @param query
	 * @param cls
	 * @return
	 */
	public static <T extends Model> T saveEntity(String dtName,String queryJson, T data) {
		DBObject dbo = ModelToDBObject(data);
		T re = null;
		if (dbo != null) {
			Map<String,Object> m=Utils.jsonToMap(queryJson);
			DBObject query=new BasicDBObject();
			for(Entry<String, Object> e: m.entrySet())
				query.put(e.getKey(), e.getValue());
			
			update(dtName,query,dbo);
			re = (T) DBObjectToModel(dbo, data.getClass());
		}
		return re;
	}

	private static <T extends Model> DBObject ModelToDBObject(T model) {
		Class<T> cls = (Class<T>) model.getClass();
		DBObject dbobj = new BasicDBObject();
		String field;
		Object value;
		for (Field f : cls.getDeclaredFields()) {
			try {
				field = f.getName();
				value = ConfigHelper.getAttributeValue(model, field);
				dbobj.put(field, value);
			} catch (IllegalArgumentException e) {
				log.error(e.getMessage(), e);
			}
		}

		return dbobj;
	}

	/**
	 * 数据库对象转变成实体对象
	 * 
	 * @param dbobj
	 * @param cls
	 * @return
	 */
	private static <T extends Model> T DBObjectToModel(DBObject dbobj,
			Class<T> cls) {
		T re = null;
		try {
			re = cls.newInstance();
		} catch (InstantiationException e) {
			log.error(e.getMessage(), e);
		} catch (IllegalAccessException e) {
			log.error(e.getMessage(), e);
		}
		if (re != null && dbobj != null) {
			Map<String, ?> m = dbobj.toMap();
			for (String key : m.keySet()) {
				ConfigHelper.setAttributeValue(re, key, m.get(key));
			}
			return re;
		}
		return null;
	}

	/**
	 * 查询实体
	 * 
	 * @param dtName
	 * @param query
	 * @param cls
	 * @return
	 */
	public static <T extends Model> T queryEntity(String dtName,
			DBObject query, Class<T> cls) {
		T re = null;
		DBObject one = queryOne(dtName, query);
		re = DBObjectToModel(one, cls);
		return re;
	}
	

	/**
	 * 查询实体
	 * 
	 * @param dtName
	 * @param query
	 * @param cls
	 * @return
	 */
	public static <T extends Model> T queryEntity(String dtName,
			String query, Class<T> cls) {
		T re = null;
		DBObject one = queryOne(dtName, query);
		re = DBObjectToModel(one, cls);
		return re;
	}
}
